from PyQt5.QtWidgets import QDialog
from PyQt5.QtGui import QColor
from Processor.histogram.equalize_design import  Ui_EqualizeHist

import time
import cv2
import Processor.Converter as Converter


class EqualizeHist(QDialog, Ui_EqualizeHist):

    layer = None    # 图层
    mat = None  # 原始Mat 数据
    titleChangeFlag = False  # 控制titleSize spinBox数值变化 避免死循环

    def __init__(self, parent, mat=None):
        super().__init__(parent)
        self.setupUi(self)
        self.initUI(parent)
        self.mat = mat

    def initUI(self, parent):
        self.setWindowTitle('直方图均衡控制器')
        self.CLAHE_arg_panel.hide()
        # 定位
        self.resize(180, 170)
        pos = parent.geometry()
        self.move((pos.width() - self.width())/2, (pos.height() - self.height())/2)
        #       信号
        # 确定
        self.DialogButtonBox.accepted.connect(self.accept)
        # 通道切换
        self.comboBox_channel.currentIndexChanged.connect(self.updateSlot)
        # 自适应
        self.radioButton_CLAHE.toggled.connect(self.radioButton_CLAHE_toggledSlot)
        # 锁定长宽比
        self.radioButton_fix_proportion.toggled.connect(self.radioButton_fix_proportion_toggledSlot)
        # title 水平划分
        self.spinBox_horizon_tile.valueChanged.connect(self.__tileSizeChangedSlot)
        # title 垂直划分
        self.spinBox_vertical_tile.valueChanged.connect(self.__tileSizeChangedSlot)
        # 对比度显示
        self.doubleSpinBox_clipLimit.valueChanged.connect(self.updateSlot)

    def updateSlot(self):
        channel = self.comboBox_channel.currentIndex()
        if self.radioButton_CLAHE.isChecked():
            titleH = self.spinBox_horizon_tile.value()
            titleV = self.spinBox_vertical_tile.value()
            clipLimit = self.doubleSpinBox_clipLimit.value()
            self.__CLAHE_Hist(channel, clipLimit, titleH, titleV)
        else:
            self.__equalizedHist(channel)

    def radioButton_CLAHE_toggledSlot(self):
        if self.radioButton_CLAHE.isChecked():
            self.CLAHE_arg_panel.show()
            print('转换自适应直方图')
        else:
            self.CLAHE_arg_panel.hide()
            print('关闭自适应直方图')
        self.updateSlot()
        self.update()

    def __formatTileSize(self):
        rate = self.mat.shape[0] / self.mat.shape[1]  # h/w
        if rate < 1:
            rate = 1 / rate  # w/h
            rate = int(rate)
            self.spinBox_vertical_tile.setValue(self.spinBox_horizon_tile.value() * rate)
        else:  # h/w
            rate = int(rate)
            self.spinBox_horizon_tile.setValue(self.spinBox_vertical_tile.value() * rate)

    def radioButton_fix_proportion_toggledSlot(self):
        """
        锁定划分比例
        :return:
        """
        if self.radioButton_fix_proportion.isChecked():
            self.__formatTileSize()

    def __tileSizeChangedSlot(self):
        if not self.titleChangeFlag:
            self.titleChangeFlag = True
            if self.radioButton_fix_proportion.isChecked():
                self.__formatTileSize()
            self.updateSlot()
            self.titleChangeFlag = False

    def __equalizedHist(self, channel=0):
        start = time.perf_counter()
        if channel == 0:
            r = range(0, 3)
        else:
            r = range(channel-1, channel)
        mat = self.mat.copy()
        for i in r:
            mat[:, :, i] = cv2.equalizeHist(mat[:, :, i])
        image = Converter.Numpy2QImage(mat)
        end = time.perf_counter()
        print('equalizedHist', '耗时：', end - start)
        self.layer.updatePixmap(image)

    def __CLAHE_Hist(self, channel=0,clipLimit=2.0, titleH=8,titleV=8):
        start = time.perf_counter()
        clahe = cv2.createCLAHE(clipLimit,(titleH, titleV))
        if channel ==0:
           r = range(0,3)
        else:
           r = range(channel-1,channel)
        mat = self.mat.copy()
        for i in r:
            mat[:,:,i] = clahe.apply(mat[:,:,i])
        image = Converter.Numpy2QImage(mat)
        end = time.perf_counter()
        print('CLAHE_Hist', '耗时：', end - start)
        self.layer.updatePixmap(image)


def newEqualizeHist(window):
    """
    :param window: 主窗体
    :return:
    """
    layer = window.currentLayer
    if layer:
        image = layer.image  # 当前图层QImage句柄
        mat = Converter.QImage2Numpy(image)
        controller = EqualizeHist(window, mat)
        controller.layer = layer
        if controller.exec_():
            pass
